﻿using NATUPNPLib;
using System;
using System.IO;
using System.Net;
using System.Text;
using System.Threading;
using System.Windows.Forms;

namespace net
{
    public partial class UserControlhttp : UserControl
    {
        private HttpListener listerner;

        private Thread threadMy;

        private string dir = @"D:\server";

        public UserControlhttp()
        {
            InitializeComponent();

            System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;

            this.Disposed += UserControlhttp_Disposed;
        }

        public UserControlhttp(string dir)
        {
            InitializeComponent();

            System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;

            this.Disposed += UserControlhttp_Disposed;

            this.dir = dir;
        }

        private void UserControlhttp_Disposed(object sender, EventArgs e)
        {
            if (threadMy != null)
            {
                //throw new NotImplementedException();
                threadMy.Abort();
            }
        }

        public void chuantou(int port)
        {
            //这里是开启一个windows服务 先开服务
            common.system.windowservice.startservice("UPnP Device Host");
            //取得本机内网地址
            string host = common.net.address.get_in_IP();

            //路由器端口
            var eport = 80;
            //内网机器端口
            var iport = 80;
            if (port != 0)
            {
                eport = port;
                eport = port;
            }

            //开启描述
            var description = "测试";
            //这里要引用 Interop.NATUPNPLib
            var upnpnat = new UPnPNAT();
            var mappings = upnpnat.StaticPortMappingCollection;
            if (mappings == null)
            {
                MessageBox.Show("没有检测到路由器，或者路由器不支持UPnP功能。");

                return;
            }

            //这是往路由器中写规则
            mappings.Add(eport, "TCP", iport, host, true, description);
        }

        public void chuantou(int eport, int iport)
        {
            //这里是开启一个windows服务 先开服务
            common.system.windowservice.startservice("UPnP Device Host");
            //取得本机内网地址
            string host = common.net.address.get_in_IP();

            //路由器端口
            //var eport = 80;
            ////内网机器端口
            //var iport = 80;
            //if (port != 0)
            //{
            //    eport = port;
            //    eport = port;
            //}

            //开启描述
            var description = "测试";
            //这里要引用 Interop.NATUPNPLib
            var upnpnat = new UPnPNAT();
            var mappings = upnpnat.StaticPortMappingCollection;
            if (mappings == null)
            {
                MessageBox.Show("没有检测到路由器，或者路由器不支持UPnP功能。");

                return;
            }

            //这是往路由器中写规则
            mappings.Add(eport, "TCP", iport, host, true, description);
        }

        public void start()
        {
            chuantou(80);

            using (listerner = new HttpListener())
            {
                //指定身份验证 Anonymous匿名访问
                listerner.AuthenticationSchemes = AuthenticationSchemes.Anonymous;

                string host = common.net.address.get_in_IP();

                //if (!string.IsNullOrEmpty(host))
                //{
                //    listerner.Prefixes.Add("http://" + host + ":80/");
                //}

                //listerner.Prefixes.Add("http://localhost:80/");

                //listerner.Prefixes.Add("http://192.168.1.1:80/");

                // listerner.Prefixes.Add("http://localhost/web/");

                //任何80端口访问都去处理
                listerner.Prefixes.Add("http://+:80/");

                listerner.Start();
                this.richTextBox1.Text += ("\nWebServer Start Successed.......");
                while (true)
                {
                    //等待请求连接
                    //没有请求则GetContext处于阻塞状态
                    HttpListenerContext ctx = listerner.GetContext();
                    ctx.Response.StatusCode = 200;//设置返回给客服端http状态代码

                    ctx.Response.ContentType = "text/html";

                    //ctx.Response.ContentEncoding = Encoding.Default;

                    string name = ctx.Request.QueryString["name"];

                    if (name != null)
                    {
                        this.richTextBox1.Text += (name);
                    }

                    //使用Writer输出http响应代码
                    using (StreamWriter writer = new StreamWriter(ctx.Response.OutputStream, Encoding.UTF8))
                    {
                        this.richTextBox1.Text += ("\n" + ctx.Request.UserHostAddress);

                        //writer.WriteLine("<html><head><title>The WebServer Test</title></head><body>");
                        //writer.WriteLine("<div style=\"height:20px;color:blue;text-align:center;\"><p> hello11 {0}</p></div>", name);
                        //writer.WriteLine("<ul>");

                        ////foreach (string header in ctx.Request.Headers.Keys)
                        ////{
                        ////    writer.WriteLine("<li><b>{0}:</b>{1}</li>", header, ctx.Request.Headers[header]);
                        ////}

                        //writer.WriteLine("<li><b>{0}:</b>{1}</li>", ctx.Request.Headers.Keys[4], ctx.Request.Headers[ctx.Request.Headers.Keys[4]]);

                        //writer.WriteLine("</ul>");
                        //writer.WriteLine("</body></html>");

                        //读取文件
                        StreamReader reader;
                        string readtext = "";
                        //string dir = @"D:\server";
                        if (ctx.Request.Url.AbsolutePath != "/")
                        {
                            if (File.Exists(dir + ctx.Request.Url.LocalPath))
                            {
                                reader = new StreamReader(dir + ctx.Request.Url.LocalPath, Encoding.UTF8);
                                //reader = new StreamReader(Path.Combine(dir, ctx.Request.Url.LocalPath.Replace("/", "")), Encoding.UTF8);
                                readtext = reader.ReadToEnd();
                                reader.Close();
                                reader.Dispose();
                            }
                        }
                        else
                        {
                            reader = new StreamReader(Path.Combine(dir, "index.htm"), Encoding.UTF8);
                            readtext = reader.ReadToEnd();
                            reader.Close();
                            reader.Dispose();
                        }
                        //writer.Encoding = Encoding.UTF8;
                        writer.Write(readtext);

                        writer.Close();
                        ctx.Response.Close();
                    }
                }

                //listerner.Stop();
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            threadMy = new Thread(start);
            threadMy.IsBackground = true;
            threadMy.Start();

            this.button1.Enabled = false;
            this.button2.Enabled = true;
        }

        private void button2_Click(object sender, EventArgs e)
        {
            threadMy.Abort();
            listerner.Stop();
            this.richTextBox1.Text += ("\nWebServer Stop .......");
            this.button1.Enabled = true;
            this.button2.Enabled = false;
        }

        private void UserControlhttp_Load(object sender, EventArgs e)
        {
            this.button2.Enabled = false;
            common.net.Router r = new common.net.Router();
            //this.label1.Text = r.getWanIP();
            this.richTextBox1.Text += r.getWanIP() + "\n";
        }

        private void button3_Click(object sender, EventArgs e)
        {
            int portwai = Convert.ToInt32(this.textBox1.Text);
            int portnei = Convert.ToInt32(this.textBox2.Text);
            chuantou(portwai, portnei);
            this.richTextBox1.Text += "\n穿透内网成功";
        }
    }
}